package com.example.processor.common;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletRequest;

import com.example.annotation.common.ReqParam;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;

/**
 * @author LiYuhang
 * @version 0.1
 * @application
 * @Date 2022/7/26 15:40
 */
public class ReqParamMethodProcessor implements HandlerMethodArgumentResolver {

    private final RequestResponseBodyMethodProcessor jsonResolver;
    private final ServletModelAttributeMethodProcessor formResolver;

    private static final String MULTIPART = "multipart";

    public ReqParamMethodProcessor() {
       /* this.messageConverters.add(new ByteArrayHttpMessageConverter());
        this.messageConverters.add(new StringHttpMessageConverter());
        this.messageConverters.add(new ResourceHttpMessageConverter(false));
        this.messageConverters.add(new SourceHttpMessageConverter());
        this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
        this.messageConverters.add(new AtomFeedHttpMessageConverter());
        this.messageConverters.add(new RssChannelHttpMessageConverter());
        this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
        this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
        this.messageConverters.add(new GsonHttpMessageConverter());
        this.messageConverters.add(new JsonbHttpMessageConverter());
        this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
        this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());*/
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();

        messageConverters.add(new MappingJackson2HttpMessageConverter());
        jsonResolver = new RequestResponseBodyMethodProcessor(messageConverters);
        formResolver = new ServletModelAttributeMethodProcessor(true);
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        ReqParam ann = methodParameter.getParameterAnnotation(ReqParam.class);

        return (ann != null);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
        NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        ServletRequest servletRequest = nativeWebRequest.getNativeRequest(ServletRequest.class);
        String contentType = servletRequest.getContentType();
        if (contentType == null) {
            throw new IllegalArgumentException("不支持contentType");
        }

        if (contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
            return jsonResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest,
                webDataBinderFactory);
        }

        if (contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
            return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest,
                webDataBinderFactory);
        }

        if (contentType.contains(MULTIPART)) {
            return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest,
                webDataBinderFactory);
        }

        throw new IllegalArgumentException("不支持contentType");
    }
}
